﻿#region << 文 件 说 明 >>

/*----------------------------------------------------------------
// 文件名称：ListExtension
// 创 建 者：杨程
// 创建时间：2021/8/27 13:18:29
// 文件版本：V1.0.0
// ===============================================================
// 功能描述：
//
//
//----------------------------------------------------------------*/

#endregion

namespace Vampirewal.Core;

/// <summary>
/// List扩展
/// </summary>
public static class ListExtension
{
    /// <summary>
    /// List转ObservableCollection
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="Source"></param>
    /// <param name="OutSource"></param>
    /// <returns></returns>
    public static ObservableCollection<T> ListToObservableCollection<T>(this List<T> Source, ObservableCollection<T> OutSource)
    {
        foreach (var item in Source)
        {
            OutSource.Add(item);
        }
        return OutSource;
    }

    /// <summary>
    /// ObservableCollection转List
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="Source"></param>
    /// <param name="OutSource"></param>
    /// <returns></returns>
    public static List<T> ObservableCollectionToList<T>(this ObservableCollection<T> Source, List<T> OutSource)
    {
        foreach (var item in Source)
        {
            OutSource.Add(item);
        }

        return OutSource;
    }

    ///// <summary>
    ///// DataTable转List
    ///// <para>仅适用于excel导入的数据，且对应实体类的属性上有<paramref name="ExportExcelAttribute"/>特性</para>
    ///// </summary>
    ///// <typeparam name="T"></typeparam>
    ///// <param name="dt"></param>
    ///// <returns></returns>
    ///// <exception cref="Exception"></exception>
    //public static List<T> ToList<T>(this DataTable dt)
    //{
    //    var list = new List<T>();
    //    var plist = new List<PropertyInfo>(typeof(T).GetProperties());
    //    foreach (DataRow item in dt.Rows)
    //    {
    //        if (item.ItemArray[0] is DBNull)
    //            continue;

    //        T s = Activator.CreateInstance<T>();
    //        for (int i = 0; i < dt.Columns.Count; i++)
    //        {
    //            //PropertyInfo info = plist.Find(p => p.Name == dt.Columns[i].ColumnName);

    //            PropertyInfo info = null;

    //            foreach (var Prop in plist)
    //            {
    //                var customAttributes = Prop.GetCustomAttributes(typeof(ExportExcelAttribute), false).ToList();

    //                foreach (var attribute in customAttributes)
    //                {
    //                    if (attribute is ExportExcelAttribute export)
    //                    {
    //                        if (export.PropertyChineseName == dt.Columns[i].ColumnName)
    //                        {
    //                            info = Prop;
    //                            continue;
    //                        }
    //                    }
    //                }

    //                if (info != null)
    //                {
    //                    continue;
    //                }
    //            }

    //            if (info != null)
    //            {
    //                try
    //                {
    //                    if (!Convert.IsDBNull(item[i]))
    //                    {
    //                        object v = null;
    //                        if (info.PropertyType.ToString().Contains("System.Nullable"))
    //                        {
    //                            v = Convert.ChangeType(item[i], Nullable.GetUnderlyingType(info.PropertyType));
    //                        }
    //                        else if (info.PropertyType.IsEnum)
    //                        {
    //                            //int enumInt = Convert.ToInt32(item[i]);

    //                            v = Enum.Parse(info.PropertyType, item[i].ToString());
    //                        }
    //                        else
    //                        {
    //                            v = Convert.ChangeType(item[i], info.PropertyType);
    //                        }

    //                        info.SetValue(s, v, null);
    //                    }
    //                }
    //                catch (Exception ex)
    //                {
    //                    throw new Exception("字段[" + info.Name + "]转换出错," + ex.Message);
    //                }
    //            }
    //        }
    //        list.Add(s);
    //    }
    //    return list;
    //}

    /// <summary>
    /// List转DataTable
    /// <para>仅适用于导出excel的数据，且对应实体类的属性上有<paramref name="ExportExcelAttribute"/>特性</para>
    /// </summary>
    //public static DataTable ToDataTable<T>(this List<T> items)
    //{
    //    var tb = new DataTable(typeof(T).Name);

    //    PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

    //    var clone = props.Clone();
    //    var cur = new List<PropertyInfo>();

    //    foreach (var item in clone as PropertyInfo[])
    //    {
    //        var export= item.GetCustomAttribute<ExportExcelAttribute>();

    //        if (export!=null&&export.IsCanExport)
    //        {
    //            tb.Columns.Add(export.PropertyChineseName, item.PropertyType);
    //            cur.Add(item);
    //        }
    //    }

    //    foreach (T item in items)
    //    {
    //        var values = new object[cur.Count];

    //        for (int i = 0; i < cur.Count; i++)
    //        {
    //            values[i] = cur[i].GetValue(item, null);
    //        }

    //        tb.Rows.Add(values);
    //    }

    //    return tb;
    //}

    /// <summary>
    /// Determine of specified type is nullable
    /// </summary>
    public static bool IsNullable(Type t)
    {
        return !t.IsValueType || (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>));
    }

    /// <summary>
    /// Return underlying type if type is Nullable otherwise return the type
    /// </summary>
    public static Type GetCoreType(Type t)
    {
        if (t != null && IsNullable(t))
        {
            if (!t.IsValueType)
            {
                return t;
            }
            else
            {
                return Nullable.GetUnderlyingType(t);
            }
        }
        else
        {
            return t;
        }
    }

    //*************************************************
    /// <summary>
    /// List转Datatable
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="table"></param>
    /// <returns></returns>
    public static IList<T> ConvertTo<T>(DataTable table)
    {
        if (table == null)
        {
            return null;
        }

        List<DataRow> rows = new List<DataRow>();

        foreach (DataRow row in table.Rows)
        {
            rows.Add(row);
        }

        return ConvertTo<T>(rows);
    }

    /// <summary>
    /// DataRow转T
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="rows"></param>
    /// <returns></returns>
    public static IList<T> ConvertTo<T>(IList<DataRow> rows)
    {
        IList<T> list = null;

        if (rows != null)
        {
            list = new List<T>();

            foreach (DataRow row in rows)
            {
                T item = CreateItem<T>(row);
                list.Add(item);
            }
        }

        return list;
    }

    /// <summary>
    /// 解析DataRow数据生成T类型的数据
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="row"></param>
    /// <returns></returns>
    public static T CreateItem<T>(DataRow row)
    {
        T obj = default(T);
        if (row != null)
        {
            obj = Activator.CreateInstance<T>();

            foreach (DataColumn column in row.Table.Columns)
            {
                PropertyInfo prop = obj.GetType().GetProperty(column.ColumnName);
                try
                {
                    object value = row[column.ColumnName];
                    prop.SetValue(obj, value, null);
                }
                catch
                {  //You can log something here
                   //throw;
                }
            }
        }

        return obj;
    }
}